<?php
declare(strict_types=1);

require __DIR__ . '/../vendor/autoload.php';

use Frontend\Http\ApiClient;
use Frontend\Middleware\Auth;
use Frontend\Router;

$config = require __DIR__ . '/../config/config.php';
$apiClient = new ApiClient($config['api_base_url']);
$router = new Router();

$render = function (string $view, array $data = []) use ($config, $apiClient): void {
    $user = Auth::currentUser($apiClient);
    extract($data);
    require __DIR__ . '/../src/Views/pages/' . $view . '.php';
};

$router->get('/', function () use ($render): void {
    $render('home');
});

$router->get('/login', function () use ($apiClient, $render): void {
    if (Auth::currentUser($apiClient)) {
        header('Location: /');
        exit;
    }
    $error = !empty($_GET['error']) ? ['message' => $_GET['error']] : null;
    $render('login', ['error' => $error]);
});

$router->post('/login', function () use ($apiClient, $render): void {
    $payload = [
        'email' => $_POST['email'] ?? '',
        'password' => $_POST['password'] ?? '',
    ];
    if (!empty($_POST['otp_code'])) {
        $payload['otp_code'] = $_POST['otp_code'];
    }
    $response = $apiClient->post('/auth/login', $payload);
    if ($response['status'] >= 400) {
        $render('login', ['error' => $response['data']]);
        return;
    }
    $next = $_GET['next'] ?? '/';
    header('Location: ' . $next);
});

$router->get('/register', function () use ($render): void {
    $render('register');
});

$router->post('/register', function () use ($apiClient, $render): void {
    $payload = [
        'email' => $_POST['email'] ?? '',
        'password' => $_POST['password'] ?? '',
        'role' => 'user',
    ];
    $response = $apiClient->post('/auth/register', $payload);
    if ($response['status'] >= 400) {
        $render('register', ['error' => $response['data']]);
        return;
    }
    header('Location: /login');
});

$router->get('/logout', function () use ($render): void {
    Auth::logout();
    header('Location: /login');
});

$router->get('/strategies', function () use ($apiClient, $render): void {
    Auth::requireLogin($apiClient);
    $strategies = $apiClient->get('/scripts/market');
    $subscriptions = $apiClient->get('/subscriptions');
    $subscriptionMap = [];
    if ($subscriptions['status'] === 200 && is_array($subscriptions['data'])) {
        foreach ($subscriptions['data'] as $item) {
            $subscriptionMap[$item['script_code']] = $item;
        }
    }
    $render('strategies', [
        'strategies' => $strategies['data'] ?? [],
        'subscriptionMap' => $subscriptionMap,
    ]);
});

$router->post('/strategies/subscribe', function () use ($apiClient): void {
    Auth::requireLogin($apiClient);
    $payload = [
        'script_code' => $_POST['script_code'] ?? '',
        'enabled' => isset($_POST['enabled']),
        'allocation' => ['mode' => 'fixed_quote', 'value' => (float) ($_POST['allocation'] ?? 0)],
    ];
    $apiClient->post('/subscriptions', $payload);
    header('Location: /strategies?saved=1');
});

$router->get('/strategies/{code}', function (array $params) use ($apiClient, $render): void {
    Auth::requireLogin($apiClient);
    $code = $params['code'];
    $strategies = $apiClient->get('/scripts/market');
    $script = null;
    foreach (($strategies['data'] ?? []) as $item) {
        if ($item['code'] === $code) {
            $script = $item;
            break;
        }
    }
    if (!$script) {
        http_response_code(404);
        $render('404');
        return;
    }
    $subs = $apiClient->get('/subscriptions');
    $subscription = null;
    if ($subs['status'] === 200) {
        foreach ($subs['data'] as $item) {
            if ($item['script_code'] === $code) {
                $subscription = $item;
                break;
            }
        }
    }
    $snapshot = $apiClient->get('/orders/snapshot');
    $orders = [];
    if ($snapshot['status'] === 200) {
        foreach ($snapshot['data']['orders'] ?? [] as $order) {
            if (($order['symbol'] ?? '') === ($script['symbols'][0] ?? '')) {
                $orders[] = $order;
            }
        }
    }
    $render('strategy_detail', [
        'script' => $script,
        'subscription' => $subscription,
        'orders' => $orders,
    ]);
});

$router->get('/portfolio', function () use ($apiClient, $render): void {
    Auth::requireLogin($apiClient);
    $snapshot = $apiClient->get('/orders/snapshot');
    $portfolio = $snapshot['data']['portfolio'] ?? [];
    $render('portfolio', ['portfolio' => $portfolio]);
});

$router->get('/orders', function () use ($apiClient, $render): void {
    Auth::requireLogin($apiClient);
    $status = $_GET['status'] ?? '';
    $snapshot = $apiClient->get('/orders/snapshot');
    $orders = $snapshot['data']['orders'] ?? [];
    if ($status) {
        $orders = array_values(array_filter($orders, fn ($o) => ($o['status'] ?? '') === $status));
    }
    $render('orders', [
        'orders' => $orders,
        'filterStatus' => $status,
    ]);
});

$router->get('/settings', function () use ($apiClient, $render): void {
    $user = Auth::requireLogin($apiClient);
    $accountsResp = $apiClient->get('/users/accounts');
    $flash = !empty($_GET['success']) ? ['message' => '设置已保存'] : null;
    $render('settings', [
        'user' => $user,
        'accounts' => $accountsResp['data'] ?? [],
        'flash' => $flash,
    ]);
});

$router->post('/settings/toggle', function () use ($apiClient): void {
    Auth::requireLogin($apiClient);
    $payload = [
        'tv_enabled' => isset($_POST['tv_enabled']),
        'global_pause' => isset($_POST['global_pause']),
    ];
    $apiClient->patch('/users/me', $payload);
    header('Location: /settings?success=1');
});

$router->post('/settings/bind', function () use ($apiClient): void {
    Auth::requireLogin($apiClient);
    $payload = [
        'account_name' => $_POST['account_name'] ?? '',
        'api_key' => $_POST['api_key'] ?? '',
        'api_secret' => $_POST['api_secret'] ?? '',
    ];
    $apiClient->post('/users/accounts/bind', $payload);
    header('Location: /settings?success=1');
});

$router->get('/admin/overview', function () use ($apiClient, $render): void {
    Auth::requireAdmin($apiClient);
    $signalsResp = $apiClient->get('/webhooks/tv/recent-signals');
    $ordersResp = $apiClient->get('/orders/admin/recent');
    $signals = $signalsResp['data'] ?? [];
    $orders = $ordersResp['data'] ?? [];
    $filled = count(array_filter($orders, fn ($o) => ($o['status'] ?? '') === 'filled'));
    $successRate = count($orders) ? round(($filled / count($orders)) * 100, 2) . '%' : '0%';
    $errorTop = [];
    foreach ($orders as $order) {
        if (!empty($order['error'])) {
            $errorTop[$order['error']] = ($errorTop[$order['error']] ?? 0) + 1;
        }
    }
    arsort($errorTop);
    $render('admin_overview', [
        'signals' => $signals,
        'orders' => $orders,
        'stats' => [
            'signals24h' => count($signals),
            'successRate' => $successRate,
            'topErrors' => array_slice($errorTop, 0, 3, true),
        ],
    ]);
});

$adminStrategiesPage = function (?array $created = null, ?string $flash = null) use ($apiClient, $render): void {
    Auth::requireAdmin($apiClient);
    $scriptsResp = $apiClient->get('/scripts');
    $render('admin_strategies', [
        'scripts' => $scriptsResp['data'] ?? [],
        'created' => $created,
        'flash' => $flash,
    ]);
};

$router->get('/admin/strategies', function () use ($adminStrategiesPage): void {
    $adminStrategiesPage();
});

$router->post('/admin/strategies/create', function () use ($apiClient, $adminStrategiesPage): void {
    $symbols = array_map('trim', explode(',', $_POST['symbols'] ?? ''));
    $payload = [
        'code' => $_POST['code'] ?? '',
        'name' => $_POST['name'] ?? '',
        'connector' => $_POST['connector'] ?? 'gate_io_perpetual',
        'symbols' => array_values(array_filter($symbols)),
        'default_target' => ['mode' => 'fixed_quote', 'value' => (float) ($_POST['default_value'] ?? 100)],
        'rate_limit_per_min' => (int) ($_POST['rate'] ?? 0) ?: null,
    ];
    $resp = $apiClient->post('/scripts', $payload);
    if ($resp['status'] >= 400) {
        $adminStrategiesPage(null, $resp['data']['detail'] ?? '创建失败');
        return;
    }
    $adminStrategiesPage($resp['data'], null);
});

$router->post('/admin/strategies/{id}/pause', function (array $params) use ($apiClient): void {
    Auth::requireAdmin($apiClient);
    $apiClient->post('/scripts/' . $params['id'] . '/pause', []);
    header('Location: /admin/strategies');
});

$router->post('/admin/strategies/{id}/resume', function (array $params) use ($apiClient): void {
    Auth::requireAdmin($apiClient);
    $apiClient->post('/scripts/' . $params['id'] . '/resume', []);
    header('Location: /admin/strategies');
});

$router->post('/admin/strategies/{id}/rotate', function (array $params) use ($apiClient, $adminStrategiesPage): void {
    Auth::requireAdmin($apiClient);
    $resp = $apiClient->post('/scripts/' . $params['id'] . '/rotate-secret', []);
    $adminStrategiesPage($resp['data'] ?? null, null);
});

$router->get('/admin/subscriptions', function () use ($apiClient, $render): void {
    Auth::requireAdmin($apiClient);
    $resp = $apiClient->get('/subscriptions/admin/all');
    $render('admin_subscriptions', ['subscriptions' => $resp['data'] ?? []]);
});

$router->get('/admin/broadcast', function () use ($apiClient, $render): void {
    Auth::requireAdmin($apiClient);
    $groups = $apiClient->get('/admin/groups');
    $render('admin_broadcast', ['groups' => $groups['data'] ?? [], 'results' => null, 'error' => null]);
});

$router->post('/admin/broadcast', function () use ($apiClient, $render): void {
    Auth::requireAdmin($apiClient);
    $payload = [
        'group_id' => (int) ($_POST['group_id'] ?? 0),
        'connector' => $_POST['connector'] ?? '',
        'symbol' => $_POST['symbol'] ?? '',
        'trade_type' => $_POST['trade_type'] ?? 'BUY',
        'order_type' => $_POST['order_type'] ?? 'MARKET',
        'position_action' => $_POST['position_action'] ?? 'OPEN',
        'invest_percent' => (float) ($_POST['invest_percent'] ?? 0),
    ];
    if (!empty($_POST['price'])) {
        $payload['price'] = (float) $_POST['price'];
    }
    if ($payload['invest_percent'] <= 0 || $payload['invest_percent'] > 100) {
        $groupsResp = $apiClient->get('/admin/groups');
        $render('admin_broadcast', [
            'groups' => $groupsResp['data'] ?? [],
            'results' => null,
            'error' => '投入百分比需在 0 到 100 之间',
        ]);
        return;
    }
    $groupsResp = $apiClient->get('/admin/groups');
    $resp = $apiClient->post('/admin/broadcast', $payload);
    $error = $resp['status'] >= 400 ? ($resp['data']['detail'] ?? '广播失败') : null;
    $render('admin_broadcast', [
        'groups' => $groupsResp['data'] ?? [],
        'results' => $resp['data']['results'] ?? null,
        'error' => $error,
    ]);
});

$router->get('/admin/risk', function () use ($apiClient, $render): void {
    Auth::requireAdmin($apiClient);
    $resp = $apiClient->get('/admin/risk-config');
    $render('admin_risk', ['riskConfig' => $resp['data'] ?? []]);
});

$router->get('/admin/audit', function () use ($apiClient, $render): void {
    Auth::requireAdmin($apiClient);
    $query = array_intersect_key($_GET, array_flip(['from', 'to', 'script', 'user', 'status', 'limit', 'format']));
    $queryString = http_build_query(array_merge($query, ['format' => $query['format'] ?? 'json']));
    $endpoint = '/admin/audit' . ($queryString ? ('?' . $queryString) : '');
    $resp = $apiClient->get($endpoint);
    if (($query['format'] ?? '') === 'csv') {
        header('Content-Type: text/csv');
        echo $resp['data']['raw'] ?? '';
        return;
    }
    $render('admin_audit', [
        'logs' => $resp['data'] ?? ['items' => []],
        'query' => $query,
    ]);
});

$router->dispatch($_SERVER['REQUEST_URI'], $_SERVER['REQUEST_METHOD']);
